using System;
using System.IO;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;

[CustomPropertyDrawer(typeof(FieldDefinition))]
public class FieldDefinitionEditor : PropertyDrawer
{
    private string GetVisualTreeAssetPath()
    {
        // 1. 获取当前脚本的路径
        string[] guids = AssetDatabase.FindAssets($"t:Script {nameof(FieldDefinitionEditor)}");
        string scriptPath = AssetDatabase.GUIDToAssetPath(guids[0]); // 将GUID转换为资源路径[citation:3]
        string scriptDirectory = Path.GetDirectoryName(scriptPath);

        // 2. 假设UXML文件与脚本在同一目录下，名为 "MyUI.uxml"
        string uxmlRelativePath = $"{nameof(FieldDefinitionEditor)}.uxml";
        string fullUxmlPath = Path.Combine(scriptDirectory, uxmlRelativePath).Replace("\\", "/");
        
        return fullUxmlPath;
    }
    
    public override VisualElement CreatePropertyGUI(SerializedProperty property)
    {
        var nameProperty = property.FindPropertyRelative("Name");
        var typeProperty = property.FindPropertyRelative("Type");
        var defaultValueProperty = property.FindPropertyRelative("DefaultValue");

        var path = GetVisualTreeAssetPath();
        var root =  AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(path).CloneTree();
        
        //名称输入框
        var nameField = root.Q<PropertyField>("NameField");
        nameField.BindProperty(nameProperty);
        
        //int,bool,float 
        var intField = root.Q<IntegerField>("IntField");
        intField.value = int.TryParse(defaultValueProperty.stringValue, out var intResult) ? intResult : 0;
        intField.RegisterValueChangedCallback(evt =>
        {
            defaultValueProperty.stringValue = evt.newValue.ToString();
            property.serializedObject.ApplyModifiedProperties();
        });
        var floatField = root.Q<FloatField>("FloatField");
        floatField.value = float.TryParse(defaultValueProperty.stringValue, out var floatResult) ? floatResult : 0f;
        floatField.RegisterValueChangedCallback(evt =>
        {
            defaultValueProperty.stringValue = evt.newValue.ToString();
            property.serializedObject.ApplyModifiedProperties();
        });
        var boolField = root.Q<Toggle>("BoolField");
        boolField.value = bool.TryParse(defaultValueProperty.stringValue, out var boolResult) && boolResult;
        boolField.RegisterValueChangedCallback(evt =>
        {
            defaultValueProperty.stringValue = evt.newValue.ToString();
            property.serializedObject.ApplyModifiedProperties();
        });
        
        
        var enumIndex = (FieldType)typeProperty.enumValueIndex;
        intField.style.display = enumIndex == FieldType.Int ? DisplayStyle.Flex : DisplayStyle.None;
        floatField.style.display = enumIndex == FieldType.Float ? DisplayStyle.Flex : DisplayStyle.None;
        boolField.style.display = enumIndex == FieldType.Bool ? DisplayStyle.Flex : DisplayStyle.None;
        
        //类型输入框
        var typeField = root.Q<PropertyField>("TypeField");
        typeField.BindProperty(typeProperty);
        typeField.RegisterValueChangeCallback(evt =>
        {
            var enumIndex = (FieldType)evt.changedProperty.enumValueIndex;
            intField.style.display = enumIndex == FieldType.Int ? DisplayStyle.Flex : DisplayStyle.None;
            floatField.style.display = enumIndex == FieldType.Float ? DisplayStyle.Flex : DisplayStyle.None;
            boolField.style.display = enumIndex == FieldType.Bool ? DisplayStyle.Flex : DisplayStyle.None;

            if (enumIndex == FieldType.Int)
            {
                defaultValueProperty.stringValue = intField.value.ToString();
            }
            else if (enumIndex == FieldType.Float)
            {
                defaultValueProperty.stringValue = floatField.value.ToString();
            }
            else if (enumIndex == FieldType.Bool)
            {
                defaultValueProperty.stringValue = boolField.value.ToString();
            }
            property.serializedObject.ApplyModifiedProperties();
        });
        
        return root;
    }
}